﻿using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.LinqBuilder;
using Microsoft.EntityFrameworkCore;
using Queer.Entity;
using Queer.Enum.OrganizationManage;
using Queer.IService.OrganizationManage;
using Queer.Model.Param.OrganizationManage;
using Queer.Util;
using Queer.Util.Helper;
using Queer.Util.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;


namespace Queer.Service.OrganizationManage
{
    /// <summary>
    /// 创 建：song
    /// 日 期：2020-12-04 12:41
    /// 描 述：用户信息服务类
    /// </summary>
    public class UserService : IUserService, ITransient
    {
        private readonly IRepository<UserEntity> _userDB;
        private readonly IRepository<DepartmentEntity> _departmentDB;
        private readonly IRepository<UserBelongEntity> _userBelongDB;
        public UserService(IRepository<UserEntity> userDB, IRepository<DepartmentEntity> departmentDB, IRepository<UserBelongEntity> userBelongDB)
        {
            _userDB = userDB;
            _departmentDB = departmentDB;
            _userBelongDB = userBelongDB;
        }

        #region 获取数据

        /// <summary>
        /// 带条件查询所有
        /// </summary>
        public async Task<List<UserEntity>> GetList(UserListParam param)
        {

            var data = await ListFilter(param).ToListAsync();
            return data;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<List<UserEntity>> GetPageList(UserListParam param, Pagination pagination)
        {
            var data = await ListFilter(param)
                .OrderByDescending(a => a.Id)
                .ToPagedListAsync(pagination.PageIndex, pagination.PageSize);

            // 分页参数赋值
            pagination.TotalCount = data.TotalCount;
            return data.Items.ToList();
        }

        /// <summary>
        /// 根据ID获取对象
        /// </summary>
        public async Task<UserEntity> GetEntity(long id)
        {
            var list = await _userDB.AsQueryable(p => p.Id == id).ToListAsync();
            return list.FirstOrDefault();
        }

        /// <summary>
        /// 查询多个ID主键数据
        /// </summary>
        public async Task<List<UserEntity>> GetListByIds(string ids)
        {
            if (ids.IsNullOrEmpty())
                throw new BusinessException("参数不合法！");

            var idArr = TextHelper.SplitToArray<long>(ids, ',').ToList();
            var data = await _userDB.AsQueryable(a => idArr.Contains(a.Id.GetValueOrDefault())).ToListAsync();

            return data;
        }

        /// <summary>
        /// 根据token获取用户信息
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task<OperatorInfo> GetUserByToken(string token)
        {
            if (!SecurityHelper.IsSafeSqlParam(token))
                return null;

            token = token.ParseToString().Trim();
            IQueryable<UserEntity> query = _userDB.AsQueryable(a => a.ApiToken == token);
            var operatorInfoIQ = from user in query
                                 select new OperatorInfo
                                 {
                                     UserId = user.Id,
                                     UserStatus = user.UserStatus,
                                     IsOnline = user.IsOnline,
                                     UserName = user.UserName,
                                     RealName = user.RealName,
                                     Portrait = user.Portrait,
                                     DepartmentId = user.DepartmentId,
                                     ApiToken = user.ApiToken,
                                     IsSystem = user.IsSystem,
                                     LoginUserType = user.LoginUserType,
                                     LoginUserId = user.LoginUserId
                                 };

            var operatorInfo = operatorInfoIQ.FirstOrDefault();

            if (operatorInfo != null)
            {
                // 角色
                var roleIds = await _userBelongDB
                                     .AsQueryable(false)
                                     .Where(a => a.UserId == operatorInfo.UserId && a.BelongType == UserBelongTypeEnum.Role.ParseToInt())
                                     .Select(a => a.BelongId.ParseToString())
                                     .ToListAsync();

                operatorInfo.RoleIds = string.Join(",", roleIds);

                // 部门名称
                operatorInfo.DepartmentName = await _departmentDB
                                                    .AsQueryable(false)
                                                    .Where(a => a.Id == operatorInfo.DepartmentId)
                                                    .Select(a => a.DepartmentName)
                                                    .FirstOrDefaultAsync();
            }
            return operatorInfo;
        }

        public async Task<UserEntity> CheckLogin(string userName)
        {
            var user = await _userDB.Where(t => t.UserName == userName).FirstOrDefaultAsync();
            return user;
        }

        /// <summary>
        /// 校验用户是否为管理员
        /// </summary>
        /// <returns></returns>
        public async Task<bool> CheckUserIsSystemManage(long id)
        {

            int i = await _userDB.AsQueryable(false).Where(a => a.IsSystem == 1 && a.Id == id).CountAsync();
            if (i > 0)
                return true;

            return false;
        }

        #endregion

        #region 提交数据

        public async Task SaveForm(UserEntity entity)
        {
            if (entity.Id.IsNullOrZero())
            {
                if (_userDB.Any(a => a.UserName == entity.UserName && a.IsDelete != true))
                    throw new BusinessException("用户名已存在");

                await _userDB.InsertNowAsync(entity);
            }
            else
                await _userDB.UpdateNowAsync(entity, ignoreNullValues: true);
        }

        public async Task DeleteForm(string ids)
        {
            if (string.IsNullOrWhiteSpace(ids))
                throw new BusinessException("参数不合法！");

            var _ids = ids.Split(",");

            foreach (var id in _ids)
                if (await CheckUserIsSystemManage(id.ParseToLong()))
                    throw new BusinessException("超管账号不删除");

            await _userDB.BatchFakeDeleteAsync(_ids);
        }

        /// <summary>
        /// 修改用户状态
        /// </summary>
        public async Task ChangeUserState(UserEntity entity)
        {
            if (await CheckUserIsSystemManage(entity.Id.Value))
                throw new Exception("超管账号不予修改！");

            await _userDB.UpdateIncludeNowAsync(entity, new[] { nameof(UserEntity.UserStatus) });
        }

        public async Task ResetPassword(UserEntity entity)
        {
            if (await CheckUserIsSystemManage(entity.Id.Value))
                throw new Exception("超管账号不予修改！");

            // 默认赋值
            entity.LastModifyTime = DateTime.Now;
            await _userDB.UpdateIncludeNowAsync(entity, new[] { nameof(UserEntity.Password), nameof(UserEntity.Salt) });
        }

        #endregion

        #region 私有方法

        private IQueryable<UserEntity> ListFilter(UserListParam param)
        {

            IQueryable<UserEntity> query = _userDB.AsQueryable(false).Where(x => x.IsDelete != true);

            if (param != null)
            {
                if (!string.IsNullOrEmpty(param.UserName))
                    query = query.Where(p => p.UserName.Contains(param.UserName));

                if (!string.IsNullOrEmpty(param.Mobile))
                    query = query.Where(p => p.Mobile.Contains(param.Mobile));

                if (param.UserStatus != null)
                    query = query.Where(p => p.UserStatus == param.UserStatus);

                if (param.QueryDepartmentId != null)
                    query = query.Where(p => p.DepartmentId == param.QueryDepartmentId);
            }

            query = from a in query
                    join b in _departmentDB.AsQueryable(false) on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select new UserEntity()
                    {
                        Id = a.Id,
                        Birthday = a.Birthday,
                        CreateTime = a.CreateTime,
                        DepartmentId = a.DepartmentId,
                        Email = a.Email,
                        Gender = a.Gender,
                        IsSystem = a.IsSystem,
                        Mobile = a.Mobile,
                        Remark = a.Remark,
                        UserName = a.UserName,
                        UserStatus = a.UserStatus,
                        RealName = a.RealName,
                        DepartmentName = b == null ? string.Empty : b.DepartmentName
                    };

            return query;
        }

        #endregion
    }
}
